#include "ImageOperation.h"
#include <QDebug>
#include <QCoreApplication>
#include <QDateTime>

/**
 * @brief 获取全局操作索引
 * @return 操作索引的引用
 */
int& getGlobalOperationIndex()
{
    static int s_operationIndex = 0;
    return s_operationIndex;
}

/**
 * @brief ImageOperation类的构造函数
 */
ImageOperation::ImageOperation(const QString& imageGuid,
                              ImageOperationType type,
                              const QVariant& previousValue,
                              const QVariant& newValue,
                              const std::function<bool(const QVariant&)>& undoFunc,
                              const std::function<bool(const QVariant&)>& redoFunc,
                              const QString& description,
                              const QString& tempDirectoryPath,
                              QUndoCommand *parent)
    : QUndoCommand(description, parent),
      m_imageGuid(imageGuid),
      m_type(type),
      m_previousValue(previousValue),
      m_newValue(newValue),
      m_undoFunc(undoFunc),
      m_redoFunc(redoFunc),
      m_tempDirectoryPath(tempDirectoryPath)
{
    // 如果是图像处理操作，且值包含QImage类型，将图像保存到临时文件
    if (m_type == ImageOperationType::ImageProcessing) {
        // 获取全局操作索引
        int& operationIndex = getGlobalOperationIndex();
        operationIndex++;
        
        if (m_previousValue.canConvert<QImage>() && !m_previousValue.value<QImage>().isNull() && !m_tempDirectoryPath.isEmpty()) {
            QString tempPath = generateTempImagePath(m_imageGuid, m_type, operationIndex, m_tempDirectoryPath);
            if (!tempPath.isEmpty()) {
                if (saveImageToTempFile(m_previousValue.value<QImage>(), tempPath)) {
                    // 保存临时文件路径而不是完整图像
                    m_previousValue = tempPath;
                    // 保存临时文件路径以便稍后清理
                    m_tempFiles.append(tempPath);
                }
            }
        }
        
        if (m_newValue.canConvert<QImage>() && !m_newValue.value<QImage>().isNull() && !m_tempDirectoryPath.isEmpty()) {
            QString tempPath = generateTempImagePath(m_imageGuid, m_type, operationIndex + 1, m_tempDirectoryPath);
            if (!tempPath.isEmpty()) {
                if (saveImageToTempFile(m_newValue.value<QImage>(), tempPath)) {
                    // 保存临时文件路径而不是完整图像
                    m_newValue = tempPath;
                    // 保存临时文件路径以便稍后清理
                    m_tempFiles.append(tempPath);
                }
            }
        }
    }
}

/**
 * @brief ImageOperation类的构造函数（接受OperationInfo结构体和临时目录路径）
 */
ImageOperation::ImageOperation(const OperationInfo& info,
                              const QString& tempDirectoryPath,
                              QUndoCommand *parent)
    : QUndoCommand(info.description, parent),
      m_imageGuid(info.imageGuid),
      m_type(info.type),
      m_previousValue(info.previousValue),
      m_newValue(info.newValue),
      m_undoFunc(info.undoFunc),
      m_redoFunc(info.redoFunc),
      m_tempDirectoryPath(tempDirectoryPath)
{
    // 如果是图像处理操作，且值包含QImage类型，将图像保存到临时文件
    if (m_type == ImageOperationType::ImageProcessing) {
        // 获取全局操作索引
        int& operationIndex = getGlobalOperationIndex();
        operationIndex++;
        
        if (m_previousValue.canConvert<QImage>() && !m_previousValue.value<QImage>().isNull() && !m_tempDirectoryPath.isEmpty()) {
            QString tempPath = generateTempImagePath(m_imageGuid, m_type, operationIndex, m_tempDirectoryPath);
            if (!tempPath.isEmpty()) {
                if (saveImageToTempFile(m_previousValue.value<QImage>(), tempPath)) {
                    // 保存临时文件路径而不是完整图像
                    m_previousValue = tempPath;
                    // 保存临时文件路径以便稍后清理
                    m_tempFiles.append(tempPath);
                }
            }
        }
        
        if (m_newValue.canConvert<QImage>() && !m_newValue.value<QImage>().isNull() && !m_tempDirectoryPath.isEmpty()) {
            QString tempPath = generateTempImagePath(m_imageGuid, m_type, operationIndex + 1, m_tempDirectoryPath);
            if (!tempPath.isEmpty()) {
                if (saveImageToTempFile(m_newValue.value<QImage>(), tempPath)) {
                    // 保存临时文件路径而不是完整图像
                    m_newValue = tempPath;
                    // 保存临时文件路径以便稍后清理
                    m_tempFiles.append(tempPath);
                }
            }
        }
    }
}

/**
 * @brief ImageOperation类的析构函数
 */
ImageOperation::~ImageOperation()
{
    // 清理临时文件
    for (const QString& tempPath : m_tempFiles) {
        if (!tempPath.isEmpty() && QFile::exists(tempPath)) {
            if (!QFile::remove(tempPath)) {
                qWarning() << "无法删除临时文件: " << tempPath;
            }
        }
    }
}

/**
 * @brief 执行撤销操作
 */
void ImageOperation::undo()
{
    if (m_undoFunc) {
        // 对于图像处理操作，如果值是文件路径，先加载图像
        if (m_type == ImageOperationType::ImageProcessing && m_previousValue.type() == QVariant::String) {
            QString tempPath = m_previousValue.toString();
            if (!tempPath.isEmpty()) {
                QImage image = loadImageFromTempFile(tempPath);
                if (!image.isNull()) {
                    m_undoFunc(QVariant::fromValue(image));
                    return;
                }
            }
        }
        
        // 否则直接使用原始值
        m_undoFunc(m_previousValue);
    }
}

/**
 * @brief 执行重做操作
 */
void ImageOperation::redo()
{
    if (m_redoFunc) {
        // 对于图像处理操作，如果值是文件路径，先加载图像
        if (m_type == ImageOperationType::ImageProcessing && m_newValue.type() == QVariant::String) {
            QString tempPath = m_newValue.toString();
            if (!tempPath.isEmpty()) {
                QImage image = loadImageFromTempFile(tempPath);
                if (!image.isNull()) {
                    m_redoFunc(QVariant::fromValue(image));
                    return;
                }
            }
        }
        
        // 否则直接使用原始值
        m_redoFunc(m_newValue);
    }
}

/**
 * @brief 获取图像GUID
 * @return 图像GUID
 */
QString ImageOperation::getImageGuid() const
{
    return m_imageGuid;
}

/**
 * @brief 获取操作类型
 * @return 操作类型
 */
ImageOperationType ImageOperation::getType() const
{
    return m_type;
}

/**
 * @brief 获取操作前的值
 * @return 操作前的值
 */
QVariant ImageOperation::getPreviousValue() const
{
    return m_previousValue;
}

/**
 * @brief 获取操作后的值
 * @return 操作后的值
 */
QVariant ImageOperation::getNewValue() const
{
    return m_newValue;
}

/**
 * @brief 获取操作类型对应的字符串
 * @param type 操作类型
 * @return 操作类型的字符串表示
 */
QString operationTypeToString(ImageOperationType type)
{
    switch (type) {
        case ImageOperationType::ImageProcessing:
            return "ImageProcessing";
        case ImageOperationType::ImageMeasurement:
            return "ImageMeasurement";
        case ImageOperationType::AxisParamsChange:
            return "AxisParamsChange";
        case ImageOperationType::ImageCalibration:
            return "ImageCalibration";
        case ImageOperationType::ImageZoom:
            return "ImageZoom";
        case ImageOperationType::Other:
        default:
            return "Other";
    }
}

/**
 * @brief 从字符串解析操作类型
 * @param typeStr 操作类型字符串
 * @return 对应的操作类型枚举值
 */
ImageOperationType stringToOperationType(const QString& typeStr)
{
    if (typeStr == "ImageProcessing") {
        return ImageOperationType::ImageProcessing;
    } else if (typeStr == "ImageMeasurement") {
        return ImageOperationType::ImageMeasurement;
    } else if (typeStr == "AxisParamsChange") {
        return ImageOperationType::AxisParamsChange;
    } else if (typeStr == "ImageCalibration") {
        return ImageOperationType::ImageCalibration;
    } else if (typeStr == "ImageZoom") {
        return ImageOperationType::ImageZoom;
    } else {
        return ImageOperationType::Other;
    }
}

/**
 * @brief 生成临时图像文件路径
 * @param imageGuid 图像GUID
 * @param operationType 操作类型
 * @param operationIndex 操作索引
 * @param tempDirectoryPath 临时目录路径
 * @return 临时文件路径
 */
QString generateTempImagePath(const QString& imageGuid, ImageOperationType operationType, int operationIndex, const QString& tempDirectoryPath)
{
    if (tempDirectoryPath.isEmpty()) {
        qWarning() << "临时目录路径为空，无法生成临时文件路径";
        return QString();
    }
    
    // 生成文件名，包含图像GUID、操作类型和操作索引
    QString shortGuid = imageGuid.left(8); // 使用GUID的前8位以简化文件名
    QString typeStr = operationTypeToString(operationType).toLower();
    QString timestamp = QString::number(QDateTime::currentDateTime().toMSecsSinceEpoch());
    
    QString fileName = QString("%1_%2_%3_%4.png").arg(shortGuid).arg(typeStr).arg(operationIndex).arg(timestamp);
    
    // 返回完整的临时文件路径
    return tempDirectoryPath + QDir::separator() + fileName;
}

/**
 * @brief 保存图像到临时文件
 * @param image 要保存的图像
 * @param tempPath 临时文件路径
 * @return 是否保存成功
 */
bool saveImageToTempFile(const QImage& image, const QString& tempPath)
{
    if (image.isNull() || tempPath.isEmpty()) {
        qWarning() << "无法保存空图像或使用空路径";
        return false;
    }
    
    // 确保目录存在
    QFileInfo fileInfo(tempPath);
    QString dirPath = fileInfo.path();
    QDir dir(dirPath);
    if (!dir.exists()) {
        if (!dir.mkpath(dirPath)) {
            qWarning() << "无法创建目录: " << dirPath;
            return false;
        }
    }
    
    // 保存图像
    if (!image.save(tempPath, "PNG")) {
        qWarning() << "无法保存图像到临时文件: " << tempPath;
        return false;
    }
    
    return true;
}

/**
 * @brief 从临时文件加载图像
 * @param tempPath 临时文件路径
 * @return 加载的图像，如果失败则返回空图像
 */
QImage loadImageFromTempFile(const QString& tempPath)
{
    if (tempPath.isEmpty() || !QFile::exists(tempPath)) {
        qWarning() << "临时文件不存在: " << tempPath;
        return QImage();
    }
    
    QImage image;
    if (!image.load(tempPath)) {
        qWarning() << "无法加载临时图像文件: " << tempPath;
        return QImage();
    }
    
    return image;
}
